/*
 * Copyright (C) 2010-2011 Comcast Cable.  All Rights Reserved.
 */
package com.hercules.android.receiver;

import com.hercules.android.receiver.model.objects.XREObject;
import com.hercules.android.receiver.model.objects.XREView;
import com.hercules.android.receiver.painting.views.AndroidXREView;

import java.util.Map;

/**
 * This entity stores the runtime application data needed by the receiver in order to display the application. The
 * receiver has a setter for it, so that the user may plug in an entity with more properties, some of which might be
 * needed to be set prior to starting the receiver.
 * <p>
 * <b>Thread Safety:</b> This class is mutable and not thread safe
 *
 * @author argolite, 7realm
 * @version 1.0
 */
public class ApplicationData {
    /**
     * The session GUID. This will be extracted by the server connection from the CONNECT command and set here.
     * <p>
     * It is set in the setter. It can be retrieved in the getter. It may have any value. This field will be injected by
     * the application using this class.
     */
    private String sessionGUID;
    /**
     * The application version. This will be extracted by the proper handler from the CONNECT command and set here.
     * <p>
     * It is set in the setter. It can be retrieved in the getter. It may have any value. This field will be injected by
     * the application using this class.
     */
    private String version;
    /**
     * The key map URL. This will be extracted by the proper handler from the CONNECT command and set here.
     * <p>
     * It is set in the setter. It can be retrieved in the getter. It may have any value. This field will be injected by
     * the application using this class.
     */
    private String keyMapURL;
    /**
     * The number of bad commands that have been received. Starting value is one. The setter is only allowed to
     * increment the value, or reset it to 0. The setter will check if the maximum number of bad commands is reached, in
     * which case it will call the shutdown() method from the receiver.
     * <p>
     * It is set in the setter. It can be retrieved in the getter. It will not be a negative number. This field will be
     * injected by the application using this class.
     */
    private int badCommandAcceptCount = 0;
    /**
     * The command index of the commands being received. It's value will be incremented by the
     * XREAggregateCommandHandler every time and this handler will also check that the command index from the command is
     * a proper one.
     * <p>
     * It is set in the setter. It can be retrieved in the getter. It may have any value. This field will be injected by
     * the application using this class.
     */
    private int currentCommandIndex = -1;
    /**
     * The event index. It is used when sending an event, in order to properly index the events.
     * <p>
     * It is set in the setter. It can be retrieved in the getter. It may have any value. This field will be injected by
     * the application using this class.
     */
    private int currentEventIndex;
    /**
     * The map of XRE object ids to the XREObjects. It is used to quickly find the objects.
     * <p>
     * It is set in the setter. It can be retrieved in the getter. It may have any value. This field will be injected by
     * the application using this class.
     */
    private Map<Integer, XREObject> elementsXREIdToObject;
    /**
     * The map between the XREViews and their corresponding Views. It will contain the id of the XREView as the key, and
     * the View as the value.
     * <p>
     * It is set in the setter. It can be retrieved in the getter. It may have any value. This field will be injected by
     * the application using this class.
     */
    private Map<Integer, AndroidXREView> viewsXREIdToView;
    /**
     * The map between the views associated with a nested XREApplication and the receivers started for the nested
     * applications.
     * <p>
     * It is set in the setter. It can be retrieved in the getter. It may have any value. This field will be injected by
     * the application using this class.
     */
    private Map<Integer, AndroidReceiver> nestedXREApplicationViewsIdToReceiver;
    /**
     * The parent receiver of a nested receiver.
     * <p>
     * It is set in the setter. It can be retrieved in the getter. It may have any value. This field will be injected by
     * the application using this class.
     */
    private AndroidReceiver parentReceiver;
    /**
     * The parent view of a nested receiver.
     * <p>
     * It is set in the setter. It can be retrieved in the getter. It may have any value. This field will be injected by
     * the application using this class.
     */
    private XREView parentXREApplicationView;
    /**
     * The extra data for the painters.
     * <p>
     * It is set in the setter. It can be retrieved in the getter. It may have any value. This field will be injected by
     * the application using this class.
     */
    private Map<String, Object> extraPainterData;

    /**
     * Default empty constructor.
     */
    public ApplicationData() {
        // empty
    }

    /**
     * Gets the session GUID. This will be extracted by the server connection from the CONNECT command.
     *
     * @return the session GUID
     */
    public String getSessionGUID() {
        return sessionGUID;
    }

    /**
     * Sets the session GUID. This will be extracted by the server connection from the CONNECT command and set here.
     *
     * @param sessionGUID the session GUID
     */
    public void setSessionGUID(String sessionGUID) {
        this.sessionGUID = sessionGUID;
    }

    /**
     * Gets the application version. This will be extracted by the proper handler from the CONNECT command.
     *
     * @return the application version
     */
    public String getVersion() {
        return version;
    }

    /**
     * Sets the application version. This will be extracted by the proper handler from the CONNECT command and set here.
     *
     * @param version the application version
     */
    public void setVersion(String version) {
        this.version = version;
    }

    /**
     * Gets the key map URL, this will be extracted by the proper handler from the CONNECT command.
     *
     * @return the key map URL
     */
    public String getKeyMapURL() {
        return keyMapURL;
    }

    /**
     * Sets the key map URL. This will be extracted by the proper handler from the CONNECT command and set here.
     *
     * @param keyMapURL the key map URL
     */
    public void setKeyMapURL(String keyMapURL) {
        this.keyMapURL = keyMapURL;
    }

    /**
     * Gets the number of bad commands that have been received.
     * <p>
     * Starting value is one. The setter is only allowed to increment the value, or reset it to 0. The setter will check
     * if the maximum number of bad commands is reached, in which case it will call the shutdown() method from the
     * receiver.
     *
     * @return the number of bad commands that have been received
     */
    public int getBadCommandAcceptCount() {
        return badCommandAcceptCount;
    }

    /**
     * Increments the value of the badCommandAcceptCount by 1, and checks if the limit has been reached. If limit is
     * exceed, parent receiver will be shut down.
     */
    public void incrementBadCommandAcceptCount() {
        // increment bad command count
        badCommandAcceptCount++;
    }

    /**
     * Sets the value of the badCommandAcceptCount to 0.
     */
    public void resetBadCommandAcceptCount() {
        badCommandAcceptCount = 0;
    }

    /**
     * Gets the command index of the commands being received.
     * <p>
     * It's value will be incremented by the XREAggregateCommandHandler every time and this handler will also check that
     * the command index from the command is a proper one.
     *
     * @return the command index of the commands being received
     */
    public int getCurrentCommandIndex() {
        return currentCommandIndex;
    }

    /**
     * Sets the command index of the commands being received.
     * <p>
     * This value will be incremented by the XREAggregateCommandHandler every time and this handler will also check that
     * the command index from the command is a proper one.
     *
     * @param currentCommandIndex the command index of the commands being received
     */
    public void setCurrentCommandIndex(int currentCommandIndex) {
        this.currentCommandIndex = currentCommandIndex;
    }

    /**
     * Increments the value of the currentCommandIndex by 1.
     */
    public void incrementCurrentCommandIndex() {
        currentCommandIndex++;
    }

    /**
     * Gets the event index. It is used when sending an event, in order to properly index the events.
     *
     * @return the event index. It is used when sending an event, in order to properly index the events
     */
    public int getCurrentEventIndex() {
        return currentEventIndex;
    }

    /**
     * Sets the event index. It is used when sending an event, in order to properly index the events.
     *
     * @param currentEventIndex the event index. It is used when sending an event, in order to properly index the events
     */
    public void setCurrentEventIndex(int currentEventIndex) {
        this.currentEventIndex = currentEventIndex;
    }

    /**
     * Gets the map of XRE object ids to the XREObjects.
     *
     * @return the map of XRE object ids to the XREObjects
     */
    public Map<Integer, XREObject> getElementsXREIdToObject() {
        return elementsXREIdToObject;
    }

    /**
     * Sets the map of XRE object ids to the XREObjects.
     *
     * @param elementsXREIdToObject the map of XRE object ids to the XREObjects
     */
    public void setElementsXREIdToObject(Map<Integer, XREObject> elementsXREIdToObject) {
        this.elementsXREIdToObject = elementsXREIdToObject;
    }

    /**
     * Gets the map between the XREViews and their corresponding Views.
     *
     * @return the map between the XREViews and their corresponding Views
     */
    public Map<Integer, AndroidXREView> getViewsXREIdToView() {
        return viewsXREIdToView;
    }

    /**
     * Sets the map between the XREViews and their corresponding Views.
     *
     * @param viewsXREIdToView the map between the XREViews and their corresponding Views
     */
    public void setViewsXREIdToView(Map<Integer, AndroidXREView> viewsXREIdToView) {
        this.viewsXREIdToView = viewsXREIdToView;
    }

    /**
     * Gets the map between the views associated with a nested XREApplication and the receivers.
     *
     * @return the map between the views associated with a nested XREApplication and the receivers
     */
    public Map<Integer, AndroidReceiver> getNestedXREApplicationViewsIdToReceiver() {
        return nestedXREApplicationViewsIdToReceiver;
    }

    /**
     * Sets the map between the views associated with a nested XREApplication and the receivers.
     *
     * @param nestedXREApplicationViewsIdToReceiver the map between the views associated with a nested XREApplication
     * and the receivers
     */
    public void setNestedXREApplicationViewsIdToReceiver(
        Map<Integer, AndroidReceiver> nestedXREApplicationViewsIdToReceiver) {
        this.nestedXREApplicationViewsIdToReceiver = nestedXREApplicationViewsIdToReceiver;
    }

    /**
     * Gets the parent receiver of a nested receiver.
     *
     * @return the parent receiver of a nested receiver
     */
    public AndroidReceiver getParentReceiver() {
        return parentReceiver;
    }

    /**
     * Sets the parent receiver of a nested receiver.
     *
     * @param parentReceiver the parent receiver of a nested receiver
     */
    public void setParentReceiver(AndroidReceiver parentReceiver) {
        this.parentReceiver = parentReceiver;
    }

    /**
     * Gets the parent view of a nested receiver.
     *
     * @return the parent view of a nested receiver
     */
    public XREView getParentXREApplicationView() {
        return parentXREApplicationView;
    }

    /**
     * Sets the parent view of a nested receiver.
     *
     * @param parentXREApplicationView the parent view of a nested receiver
     */
    public void setParentXREApplicationView(XREView parentXREApplicationView) {
        this.parentXREApplicationView = parentXREApplicationView;
    }

    /**
     * Gets the extra data for the painters.
     *
     * @return the extra data for the painters
     */
    public Map<String, Object> getExtraPainterData() {
        return extraPainterData;
    }

    /**
     * Sets the extra data for the painters.
     *
     * @param extraPainterData the extra data for the painters
     */
    public void setExtraPainterData(Map<String, Object> extraPainterData) {
        this.extraPainterData = extraPainterData;
    }
}